This is an example of using RadarSimPy to simulate an FMCW radar with a corner reflector model (not an ideal point target). Ray-Tracing/Shoot-and-Bounce-Rays method is used in RadarSimPy. The ray-tracing engine RadarSimC, which is built with C++, is integrated in RadarSimPy.
RadarSimPyis a radar simulation package built with python. Contact me if you are interested in this module.
This notebook is available on my GitHub.
The following table lists the basic parameters of the radar transmitter.
| Parameter | Variable in RadarSimPy |
Value |
|---|---|---|
| Center frequency ($f_c$) | fc | 77 GHz |
| Bandwidth ($B$) | bandwidth | 100 MHz |
| Transmitted power ($P_t$) | tx_power | 10 dBm |
| Rising or falling chirp | slop_type | rising |
| Chirp repetition period ($CRP$) | repetition_period | 100 us |
| Chirp length ($T$) | pulse_length | 80 us |
| Number of chirps | pulses | 256 |
| Chirp start delay | delay | 0 s |
The parameters of the receiver are listed in the table below.
| Parameter | Variable in RadarSimPy |
Value |
|---|---|---|
| Sampling rate ($f_s$) | fs | 2 Msps |
| Noise figure ($NF$) | noise_figure | 12 dB |
| RF gain/loss ($G_{rf}$) | rf_gain | 20 dB |
| Load resistor ($R_L$) | load_resistor | 500 $\Omega$ |
| Baseband voltage gain ($G_{BB}$) | baseband_gain | 30 dB |
import numpy as np
from radarsimpy import Radar, Transmitter, Receiver
angle = np.arange(-90, 91, 1)
pattern = 20 * np.log10(np.cos(angle / 180 * np.pi) + 0.01)
tx_channel = dict(
location=(0, 0, 0),
azimuth_angle=angle,
azimuth_pattern=pattern,
elevation_angle=angle,
elevation_pattern=pattern,
)
tx = Transmitter(fc=77e9,
pulse_length=80e-6,
bandwidth=100e6,
tx_power=15,
slop_type='rising',
repetition_period=100e-6,
pulses=256,
channels=[tx_channel])
rx_channel = dict(
location=(0, 0, 0),
azimuth_angle=angle,
azimuth_pattern=pattern,
elevation_angle=angle,
elevation_pattern=pattern,
)
rx = Receiver(fs=2e6,
noise_figure=8,
rf_gain=20,
load_resistor=500,
baseband_gain=30,
channels=[rx_channel])
aperture = dict(
phi=0,
theta=90,
location=[0,0,0],
extension = [0.25,0.25,0.25,0.25]
)
radar = Radar(transmitter=tx, receiver=rx, type='FMCW', aperture=aperture)
The corner reflector model is with .stl. It can be imported by using numpy-stl module.
target_1 = {
'model': '../models/cr.stl',
'location': (50, 0, 0),
'speed': (-5, 0, 0)
}
targets = [target_1]
Plot the 3D mesh of the corner reflector
from stl import mesh
import plotly.graph_objs as go
from plotly.offline import iplot
mesh_data = mesh.Mesh.from_file('../models/cr.stl')
x = np.ravel(mesh_data.vectors[:, :, 0])
y = np.ravel(mesh_data.vectors[:, :, 1])
z = np.ravel(mesh_data.vectors[:, :, 2])
cr = go.Mesh3d(x=x, y=y, z=z, opacity=1,
i=np.arange(0, np.shape(mesh_data.vectors)[0]*3, 3),
j=np.arange(1, np.shape(mesh_data.vectors)[0]*3, 3),
k=np.arange(2, np.shape(mesh_data.vectors)[0]*3, 3),
)
fig = go.Figure(data=[cr])
iplot(fig)
from radarsimpy import scene
import time
tic = time.time()
rays = scene(radar,targets, density=1)
toc = time.time()
print('Exection time:', toc-tic, 's')
print('Number of received rays:', len(rays))
import radarsimpy.simulator as sim
data = sim.run_simulator(radar, rays, is_raytracing=True, correction=-42)
baseband = data['baseband']
from scipy import signal
import radarsimpy.processing as proc
range_window = signal.chebwin(radar.samples_per_pulse, at=60)
range_profile = proc.cal_range_profile(radar, baseband, range_window)
temp = np.abs(range_profile[0, :, :])
temp = 20 * np.log10(temp + 0.001)
range_axis = np.linspace(
0, radar.max_range, radar.samples_per_pulse, endpoint=False)
doppler_axis = np.linspace(
0, radar.transmitter.pulses, radar.transmitter.pulses, endpoint=False)
data = [go.Surface(x=range_axis, y=doppler_axis, z=temp, colorscale='Rainbow')]
layout = go.Layout(
title='Range Profile',
height=800,
scene=dict(
xaxis=dict(title='Range (m)'),
yaxis=dict(title='Chirp'),
zaxis=dict(title='Amplitude (dB)'),
aspectmode='cube',
),
margin=dict(l=0, r=0, b=60, t=100),
legend=dict(orientation='h'),
)
fig = go.Figure(data=data, layout=layout)
iplot(fig)
doppler_window = signal.chebwin(radar.transmitter.pulses, at=60)
range_doppler = proc.cal_range_doppler(
radar, range_profile, doppler_window, fft_shift=False)
temp = np.abs(range_doppler[0, :, :])
temp = 20 * np.log10(temp)
range_axis = np.linspace(
0, radar.max_range, radar.samples_per_pulse, endpoint=False)
doppler_axis = np.linspace(
-radar.unambiguous_speed, 0, radar.transmitter.pulses, endpoint=False)
data = [go.Surface(x=range_axis, y=doppler_axis, z=temp, colorscale='Rainbow')]
layout = go.Layout(
title='Range Doppler',
height=800,
scene=dict(
xaxis=dict(title='Range (m)'),
yaxis=dict(title='Velocity (m/s)'),
zaxis=dict(title='Amplitude (dB)'),
aspectmode='cube',
),
margin=dict(l=0, r=0, b=60, t=100),
legend=dict(orientation='h'),
)
fig = go.Figure(data=data, layout=layout)
iplot(fig)